#!/bin/sh

. "$SPEC_PATH/abstract/patroni"

. "$SPEC_PATH/abstract/sql-scripts"

e2e_test_extra_hash() {
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/abstract/patroni")"
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/abstract/sql-scripts")"
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/sql-scripts.sakila.sql")"
}

e2e_test_install() {
  CLUSTER_NAME="$(get_sgshardedcluster_name "$SPEC_NAME")"

  install_minio

  cat << 'EOF' | kubectl create -n "$CLUSTER_NAMESPACE" secret generic sql-scripts-sakila-user \
    --from-literal=create-sakila-user.sql="$(cat)"
DO $$
BEGIN
  IF NOT EXISTS (SELECT * FROM pg_roles WHERE rolname = 'sakila') THEN
    EXECUTE 'CREATE USER sakila WITH PASSWORD ''sakila'';';
  END IF;
END$$;
EOF

  kubectl create -n "$CLUSTER_NAMESPACE" configmap sql-scripts-sakila-schema \
    --from-file=create-sakila-schema.sql="$SPEC_PATH/sql-scripts.sakila.sql"

  create_or_replace_sharded_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE" "3" "2"

  deploy_curl_pod "$CLUSTER_NAMESPACE"

  wait_pods_running "$CLUSTER_NAMESPACE" 7
  wait_sharded_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"
}

e2e_test() {
  run_test "Checking that is possible to connect using services is working" service_check

  run_test "Checking that sharded technology is configured and working" sharded_check

  run_test "Check that pgbouncer database is accesible using the service" pgbouncer_database_check

  run_test "Checking that managed SQL is working" check_managed_sql_is_working
}

service_check() {
  RESPONSE_PRIMARY="$(run_query -c "$CLUSTER_NAME-coord" -h "$CLUSTER_NAME" -i 1 -p 5432)"

  if [ "$RESPONSE_PRIMARY" = "1" ]
  then
    success "Connections are possible using services"
  else
    fail "Cannot connect to primary db using a kubernetes service"
  fi
}

sharded_check() {
  local RESULT EXIT_CODE
  try_function wait_until eval 'run_query -c "$CLUSTER_NAME-coord" -h "$CLUSTER_NAME" -i 1 -p 5432 \
    -d ddp -q "SELECT COUNT(*) FROM ddp_get_shard_status_connection()" | grep -xF 2'

  if [ "$EXIT_CODE" = 0 ]
  then
    success "Sharding coordinator service is working"
  else
    fail "Sharding coordinator service is not working"
  fi

  try_function wait_until eval 'run_query -c "$CLUSTER_NAME-coord" -h "$CLUSTER_NAME" -i 1 -p 5432 \
    -d ddp -q "SELECT COUNT(*) FROM ddp_get_shard_status_connection()" | grep -xF 2'

  if [ "$EXIT_CODE" = 0 ]
  then
    success "Sharding primary coordinator service is working"
  else
    fail "Sharding primary coordinator service is not working"
  fi

  try_function wait_until eval 'run_query -c "$CLUSTER_NAME-coord" -h "$CLUSTER_NAME-shards" -i 1 -p 5432 \
    -d ddp -q "SELECT pg_is_in_recovery()" | grep -xF f'

  if [ "$EXIT_CODE" = 0 ]
  then
    success "Sharding shards service is working"
  else
    fail "Sharding shards service is not working"
  fi
}

pgbouncer_database_check() {
  if kubectl exec -n "$CLUSTER_NAMESPACE" "${CLUSTER_NAME}-coord-0" -c "postgres-util" -- env \
    PGPASSWORD="$(kubectl -n "$CLUSTER_NAMESPACE" get secrets "$CLUSTER_NAME-coord" \
      -o jsonpath='{.data.pgbouncer-admin-password}' | base64 -d)" \
    PGCONNECT_TIMEOUT="$((5 + E2E_TIMEOUT / 10))" \
    psql -q -t -A -U pgbouncer_admin -d pgbouncer -h "$CLUSTER_NAME" -c "SHOW FDS" >/dev/null
  then
    success "psql could connect to the pgbouncer database with pgobuncer_admin using service"
  else
    fail "psql could not connect to the pgbouncer database with pgobuncer_admin using service"
  fi

  if kubectl exec -n "$CLUSTER_NAMESPACE" "${CLUSTER_NAME}-coord-0" -c "postgres-util" -- env \
    PGPASSWORD="$(kubectl -n "$CLUSTER_NAMESPACE" get secrets "$CLUSTER_NAME-coord" \
      -o jsonpath='{.data.pgbouncer-stats-password}' | base64 -d)" \
    PGCONNECT_TIMEOUT="$((5 + E2E_TIMEOUT / 10))" \
    psql -q -t -A -U pgbouncer_stats -d pgbouncer -h "$CLUSTER_NAME" -c "SHOW VERSION" >/dev/null
  then
    success "psql could connect to the pgbouncer database with pgobuncer_stats using service"
  else
    fail "psql could not connect to the pgbouncer database with pgobuncer_stats using service"
  fi
}

check_managed_sql_is_working() {
  local NODE=0
  local DATABASE=ddp
  check_user_on_sharded_primary
  check_database_on_sharded_primary
  check_schema_on_sharded_primary
}
